package lexer;

import java.util.ArrayList;
import java.util.LinkedList;

/**
 * Creates a meaningful error message for every token in a list of tokens
 * depending on its type and content
 * 
 * @author Caroline
 *
 */

public class ErrorMessageCreator {
	ArrayList<String> fileContent;

	public ErrorMessageCreator(ArrayList<String> fileContent) {
		this.fileContent = fileContent;
	}
	/**
	 * Iterates through a list of tokens  
	 * 
	 * @param tokens
	 * @return
	 */
	public LinkedList<Token> addErrorMessagesToTokens (LinkedList<Token> tokens) {
		
		LinkedList<Token> tokensWithMessage = new LinkedList<Token>();
		String message = "";
		
		for (Token token : tokens) {
			// displays line before the error, providing there is one
			if (token.getFileLine() > 1) {
				message += fileContent.get(token.getFileLine() - 2) + "\n";
			}
			// displays the line the error is in and points out which part of the line contains an error
			message += fileContent.get(token.getFileLine() - 1) + "\t <<<< ERROR on this line on token " + getTokenRepresentation(token) + "\n";
			// displays line after the error, providing there is one
			if (token.getFileLine() < fileContent.size()) {
				message += fileContent.get(token.getFileLine()) + "\n";
			}
			// error message is added to the token and get's reset
			token.setErrorMessage(message);
			tokensWithMessage.add(token);
			message = "";
		}
		
		return tokensWithMessage;
	}
	
	/**
	 * describes a token depending on its type
	 * 
	 * @param token
	 * @return meaningful description of the token
	 */
	private String getTokenRepresentation(Token token) {
		TokenType type = token.getType();
		
		switch (type) {
		
		case NUMBER:
			return token.contents;
		case IDENTIFIER:
			return token.contents;
		case LEFT_BRACKET:
			return "(";
		case RIGHT_BRACKET:
			return ")";
		case BEGIN_PROC:
			return "PROC";
		case IF:
			return "IF";
		case THEN:
			return "THEN";
		case ELSE:
			return "ELSE";
		case ENDIF:
			return "ENDIF";
		case FORWARD:
			return "FORWARD";
		case LEFT:
			return "LEFT";
		case RIGHT:
			return "RIGHT";
		case ADD:
			return "+";
		case SUBTRACT:
			return "-";
		case MULTIPLY:
			return "*";
		case DIVIDE:
			return "/";
		case EQUALS:
			return "==";
		case NOT_EQUALS:
			return "!=";
		case GREATER_THAN:
			return ">";
		case LESS_THAN:
			return "<";
		case GREATER_THAN_OR_EQUAL:
			return ">=";
		case LESS_THAN_OR_EQUAL:
			return "<=";
		default:
			return "";
		}
		
	}
}
